<?php
namespace coser;


class Loader
{
    //prs4 命名空间长度
    protected static $prefixLengthPsr4 = [];

    //prs4 加载目录
    protected static $prefixDirPsr4 = [];

    //自动加载方法
    public static function autoload($class)
    {
        $class = str_replace('\\','/',$class);
        if($file = self::findFile($class)){
            __include_file($file);
        }
        return $file;
    }

    //psr 查找文件
    public static function findFile($class)
    {
        //获取命名空间分组
        $fisrt = $class[0];

        if(isset(self::$prefixLengthPsr4[$fisrt])){
            foreach(self::$prefixLengthPsr4[$fisrt] as $prefix => $length){
                if(0 == strpos($class, $prefix)){
                    //取文件去命名空间路径
                    if($file = self::$prefixDirPsr4[$prefix] . DS . substr($class, $length + 1) . EXT){
                        return $file;
                    }
                }
            }
        }
    }

    //注册命名空间
    public static function addNamespace($namespace,$path ='')
    {
        if(is_array($namespace)){
            foreach($namespace as $prefix => $path){
                self::addPrs4($prefix, $path);
            }
        }else{
            self::addPrs4($namespace, $path);
        }
    }

    //添加Psr-4 空间
    public static function addPrs4($prefix,$path)
    {
        if(!empty($prefix)){
            if(!isset(self::$prefixDirPsr4[$prefix])){
                self::$prefixDirPsr4[$prefix] = $path;
                self::$prefixLengthPsr4[$prefix[0]][$prefix] = strlen($prefix);
            }
        }
    }

    //注册自动加载
    public static function register($autoload = null)
    {
        spl_autoload_register('\coser\\Loader::autoload',true,true);

        //添加命名空间
        self::addNamespace([
            'coser' => __COSER__,
        ]);
    }

    //实例化控制器
    public static function controller($name,$layer = 'controller')
    {
        list($module,$class) = self::getModuleAndClass($name,$layer);

        if(class_exists($class)){
            //执行请求
            return App::invokeClass($class);
        }

        throw new ClassNotFoundException('class not exists:' . $calss, $calss);
    }

    //解析模块和类名
    public static function getModuleAndClass($name,$layer)
    {
        $module = Request::instance()->module();

        $array = explode('\\', str_replace(['/', '.'], '\\', $name));
        $class = self::parseName(array_pop($array), 1);
        $path  = $array ? implode('\\', $array) . '\\' : '';

        $class = App::$namespace . '\\' .
            ($module ? $module . '\\' : '') .
            $layer . '\\' . $path . $class;

        return [$module,$class];
    }

    /**
     * 字符串命名风格转换
     * type 0 将 Java 风格转换为 C 的风格 1 将 C 风格转换为 Java 的风格
     * @access public
     * @param  string  $name    字符串
     * @param  integer $type    转换类型
     * @param  bool    $ucfirst 首字母是否大写（驼峰规则）
     * @return string
     */
    public static function parseName($name, $type = 0, $ucfirst = true)
    {
        if ($type) {
            $name = preg_replace_callback('/_([a-zA-Z])/', function ($match) {
                return strtoupper($match[1]);
            }, $name);

            return $ucfirst ? ucfirst($name) : lcfirst($name);
        }

        return strtolower(trim(preg_replace("/[A-Z]/", "_\\0", $name), "_"));
    }

}

//返回引入文件
function __include_file($file)
{
    return include $file;
}

//返回引入文件
function __require_file($file)
{
    return require $file;
}
